package com.lw.sbdemo2.common.web.json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lw.sbdemo2.common.exception.ApiException;
import com.lw.sbdemo2.common.exception.ResponseCodeEnum;
import com.lw.sbdemo2.common.utils.ValidUtil;
import com.lw.sbdemo2.common.web.anno.RequestForm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.List;
import javax.servlet.http.HttpServletRequest;

/**
 * <p>标题: @RequestForm 参数处理</p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2018</p>
 * <p>公司: 智业软件</p>
 *
 * @author LinWang
 * @date 2018-05-12 9:52
 */
@Slf4j
public class RequestFormArgResolver implements HandlerMethodArgumentResolver {

    /**
     * 用于判定是否需要处理该参数分解，返回true为需要，并会去调用下面的方法resolveArgument
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestForm.class);
    }

    /**
     * 真正用于处理参数分解的方法，返回的Object就是controller方法上的形参对象
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

        //获取注解信息
        RequestForm requestForm = parameter.getParameterAnnotation(RequestForm.class);
        String value = requestForm.value();
        if (StringUtils.isEmpty(value)) {
            value = parameter.getParameterName();
        }

        //重新获取request
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);

        //获取参数字符串
        String jsonStr = request.getParameter(value);

        //处理结果
        Object result = null;

        //JSON转换 - 暂处理List和实体
        if (ValidUtil.isNotEmptyAndNull(jsonStr)) {
            if (parameter.getParameterType() == List.class) {
                try {
                    String className = parameter.getGenericParameterType().getTypeName().replaceAll(".*<(.*)>", "$1");
                    result = JSON.parseArray(jsonStr, Class.forName(className));
                } catch (ClassNotFoundException e) {
                    //取出来是JSONObject，作为备用把
                    result = JSONArray.parseObject(jsonStr, parameter.getParameterType());
                }
            } else {
                result = JSONObject.parseObject(jsonStr, parameter.getParameterType());
            }
        }

        if (result == null) {
            throw new ApiException(ResponseCodeEnum.EX_PARAM, value);
        }

        log.info("RequestForm 注释处理 ，key：{}，result:{}", value, result);

        return result;
    }
}